﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel.DomainServices.Server;
using System.ComponentModel.DataAnnotations;
using System.Collections.ObjectModel;

namespace NetBay.Core.BusinessEntities.Workflow
{
    [DataContract]
    public class WorkflowDefinition : ReturnObject
    {
        #region Attributs
        private List<WorkflowAction> _actions = new List<WorkflowAction>();
        private List<WorkflowCondition> _conditions = new List<WorkflowCondition>();
        private List<WorkflowDefinition> _childs = new List<WorkflowDefinition>();

        #endregion

        #region Properties

        /// <summary>
        /// Get or set the Identifier
        /// </summary>
        [DataMember]
        public long Identifier { get; set; }

        /// <summary>
        /// Gets or sets the model id.
        /// </summary>
        /// <value>The model id.</value>
        [DataMember]
        public long ModelId { get; set; }

        /// Get or set the ParentIdentifier
        /// </summary>
        [DataMember]
        public Nullable<long> ParentId { get; set; }

        /// <summary>
        /// Workflow type 
        /// </summary>
        [DataMember]
        public WorkflowType WorkflowType { get; set; }

        /// <summary>
        /// Get or set the FolderTypeIdentifier
        /// </summary>
        [DataMember]
        public long FolderTypeId { get; set; }

        /// <summary>
        /// Get or set the ClassName
        /// </summary>
        [DataMember]
        public string ClassName { get; set; }

        /// <summary>
        /// Get or set the AssemblyName
        /// </summary>
        [DataMember]
        public string AssemblyName { get; set; }

        /// <summary>
        /// Get or set the Name
        /// </summary>
        [DataMember]
        public string Name { get; set; }

        /// <summary>
        /// Get or set the Description
        /// </summary>
        [DataMember]
        public string Description { get; set; }

        /// <summary>
        /// Get or set the SenderType
        /// </summary>
        [DataMember]
        public ReceiverType ReceiversType { get; set; }

        /// <summary>
        /// Get or set the SenderType
        /// </summary>
        [DataMember]
        public Nullable<long> ReceiverIndexId { get; set; }

        /// <summary>
        /// Get or set the ReceiverGroupId
        /// </summary>
        [DataMember]
        public List<long> ReceiverGroupId { get; set; }

        /// <summary>
        /// Get or set the Receivers
        /// </summary>
        [DataMember]
        public string Receivers { get; set; }

        /// <summary>
        /// Get or set the Rules
        /// </summary>
        [DataMember]
        public string Rules { get; set; }

        /// <summary>
        /// Get or set the StartDate
        /// </summary>
        [DataMember]
        public DateTime StartDate { get; set; }

        /// <summary>
        /// Get or set the EndDate
        /// </summary>
        [DataMember]
        public Nullable<DateTime> EndDate { get; set; }

        /// <summary>
        /// Gets or sets the is hierarchical.
        /// </summary>
        /// <value>The is hierarchical.</value>
        [DataMember]
        public bool IsHierarchical { get; set; }

        /// <summary>
        /// Gets or sets the has child.
        /// </summary>
        /// <value>The has child.</value>
        [DataMember]
        public bool HasChild { get; set; }

        public override string ToString()
        {
            return string.Format("Name: {0}, Identifier: {1}", Name, Identifier);
        }

        /// <summary>
        /// Get or set Actions list
        /// </summary>
        [Association("FK_Actions", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<WorkflowAction> Actions
        {
            get
            {
                return _actions;
            }
            set
            {
                _actions = value;
                ItemEntity.SetForeignKey(_actions, Key);
            }
        }

        /// <summary>
        /// Get or set Conditions list
        /// </summary>
        [Association("FK_Conditions", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<WorkflowCondition> Conditions
        {
            get
            {
                return _conditions;
            }
            set
            {
                _conditions = value;
                ItemEntity.SetForeignKey(_conditions, Key);
            }
        }

        /// <summary>
        /// Get or set Conditions list
        /// </summary>
        [Association("FK_Childs", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<WorkflowDefinition> Childs
        {
            get
            {
                return _childs;
            }
            set
            {
                _childs = value;
                ItemEntity.SetForeignKey(_childs, Key);
            }
        }

        #endregion  

        #region Public functions


        /// <summary>
        /// Gets the full name of the type.
        /// </summary>
        /// <returns></returns>
        public string GetFullTypeName()
        {
            return string.Format("{0}.{1}", AssemblyName, ClassName);
        }

        /// <summary>
        /// Determines whether [is receiver auto].
        /// </summary>
        /// <returns></returns>
        public bool IsReceiverAuto()
        {
            if (this.ReceiversType == ReceiverType.Auto)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Determines whether [is receiver index].
        /// </summary>
        /// <returns></returns>
        public bool IsReceiverIndex()
        {
            if (this.ReceiversType == ReceiverType.Index)
                return true;
            else
                return false;
        }

        public override object Clone()
        {
            return this.MemberwiseClone();
        }

        #endregion

        #region Constructors
        
        public WorkflowDefinition()
        {
            ParentId = null;
            Identifier = 0;
            StartDate = DateTime.Now;
            EndDate = null;
            ReceiversType = ReceiverType.Auto;
        }

        /// <summary>
        /// Only for error
        /// </summary>
        /// <param name="ErrorMessage"></param>
        public WorkflowDefinition(string errorMessage, Exception applicationException = null)
        : base(errorMessage, applicationException)
        {
        }
        #endregion
    }

    public abstract class WorkflowDefinitionDer : WorkflowDefinition
    {
        public abstract void SetActionsList(long wkfDefinitionId);

        public abstract void SetConditionList(long wkfDefinitionId);
    }
}